<?php

define('PATH_IMAGE_CACHE','cache');
define('DIR_IMAGE_CACHE',DIR_IMAGE.PATH_IMAGE_CACHE.DIRECTORY_SEPARATOR);
define('E_IMAGE_MEMORY','memory_limit exceeded (%s), requires %s.');

class Image { 
	function __construct(&$locator) {
		if (!is_writable(DIR_IMAGE)) exit(sprintf(E_COULD_NOT_WRITE,'image'));
		$this->request  =& $locator->get('request');
  		$this->config   =& $locator->get('config');
  		$this->language =& $locator->get('language');
  		$this->database =& $locator->get('database');
  		$this->cache	=& $locator->get('cache');
  	}
	
	function href($filename) {
		//if (@$_SERVER['HTTPS'] != 'on') {
		if ($this->request->isSecure()) {
	  		return HTTPS_IMAGE . $filename;
		} else {
	  		return HTTP_IMAGE . $filename;
		}	
	}

	function delete($image) {
		$ext = substr($image, strrpos($image, '.') + 1);
		//$wildcard=preg_replace('/\.([a-z]{3,4})$/i', '-*x*.jpg', $image);
		$wildcard=preg_replace('/\.([a-z]{3,4})$/i', '-*x*', $image);
		$files=glob(DIR_IMAGE_CACHE.$wildcard);
		array_push($files,DIR_IMAGE.$image);
		foreach ($files as $file) {
			@unlink($file);
		}
	}

	function exists($image) {
		if (file_exists(DIR_IMAGE.$image)) {
			return $image;
		}
	}

	function check_memory($size) {
		if (!function_exists('memory_get_usage')) { return false; }

		$_64k	= 65536;
		$_offset= 1.68;

		$memory_limit = (@ini_get('memory_limit')?ini_get('memory_limit'):'8M');

		preg_match('/(\d+)(.*)/', trim(strtoupper($memory_limit)), $matches);
		list($match,$memory_limit,$bytesuf) = $matches;
		switch($bytesuf) {
			case 'K':
				$bytes = 1024;
				break;
			case 'M':
				$bytes = 1048576;
				break;
			case 'G':
				$bytes = 1073741824;
		}
		
		$channels = isset($size['channels'])?$size['channels']:1;

		$memory_required = round(memory_get_usage() + ($size[0] * $size[1] * $size['bits'] * $channels / 8 + $_64k) * $_offset);
		
		if ($memory_required > ($memory_limit * $bytes)) {
			$memory_required = round($memory_required / $bytes).$bytesuf;
			@ini_set('memory_limit', $memory_required);

			// Did it work?
			$memory_limit .= $bytesuf;
			if ($memory_limit.$bytesuf == $memory_required) { return true; }
			else { die(sprintf(E_IMAGE_MEMORY,$memory_limit,$memory_required)); }
		}
		return true;
	}


  	function resize($image, $width, $height) {
    	if (!$this->config->get('config_image_resize')) {
      		return $this->href($image);
    	}

 		if ((!$image) || (!$width) || (!$height)) {
			return $image;
		} 
		
		if (!file_exists(DIR_IMAGE.$image)) {
			if (file_exists(DIR_IMAGE.NO_IMAGE)) {
				$image = NO_IMAGE; // If image doesn't exists, replace with no_image picture
			} else {
				return;	
			}
		}
 
 		$ext = substr($image, strrpos($image, '.') + 1);
 
    	//Q: Changed to allow Resized image to resize to the extension instead of forcing jpg
    	//$new_image = preg_replace('/\.([a-z]{3,4})$/i', '-' . $width . 'x' . $height . '.jpg', $image);
    	$new_image = preg_replace('/\.([a-z]{3,4})$/i', '-' . $width . 'x' . $height . '.' .$ext, $image);

    	if ((file_exists(DIR_IMAGE_CACHE . $new_image)) && (filemtime(DIR_IMAGE . $image) < filemtime(DIR_IMAGE_CACHE . $new_image))) {
      		return $this->href(PATH_IMAGE_CACHE.'/'.$new_image);
    	}

    	$size = @getimagesize(DIR_IMAGE . $image);

		$this->check_memory($size);

    	if ((!$size[0]) || (!$size[1])) {
      		return $this->href($image);
    	}

    	$scale = min($width / $size[0], $height / $size[1]);

    	if ($scale == 1) {
      		return $this->href($image);
    	}

    	$new_width   = (int)($size[0] * $scale);
    	$new_height  = (int)($size[1] * $scale);
    	$x_pos       = (int)(($width - $new_width) / 2);
    	$y_pos       = (int)(($height - $new_height) / 2);

    	$destination = imagecreatetruecolor($width, $height);
    	$background  = imagecolorallocate($destination, 255, 255, 255);
	
    	imagefilledrectangle($destination, 0, 0, $width, $height, $background);

    	switch ($size[2]) {
      		case '1':
        		$source = imagecreatefromgif(DIR_IMAGE . $image);

        		if (function_exists('imagecopyresampled')) {
          			imagecopyresampled($destination, $source, $x_pos, $y_pos, 0, 0, $new_width, $new_height, $size[0], $size[1]);
        		} else {
          			imagecopyresized($destination, $source, $x_pos, $y_pos, 0, 0, $new_width, $new_height, $size[0], $size[1]);
        		}

        		imagegif($destination, DIR_IMAGE_CACHE . $new_image, 90);

        		$image = $new_image;
        		break;	
      		case '2':
        		$source = imagecreatefromjpeg(DIR_IMAGE . $image);

        		if (function_exists('imagecopyresampled')) {
          			imagecopyresampled($destination, $source, $x_pos, $y_pos, 0, 0, $new_width, $new_height, $size[0], $size[1]);
        		} else {
          			imagecopyresized($destination, $source, $x_pos, $y_pos, 0, 0, $new_width, $new_height, $size[0], $size[1]);
        		}

        		imagejpeg($destination, DIR_IMAGE_CACHE . $new_image, 90);

        		$image = $new_image;
        		break;
      		case '3':
        		$source = imagecreatefrompng(DIR_IMAGE . $image);

        		if (function_exists('imagecopyresampled')) {
          			imagecopyresampled($destination, $source, $x_pos, $y_pos, 0, 0, $new_width, $new_height, $size[0], $size[1]);
        		} else {
          			imagecopyresized($destination, $source, $x_pos, $y_pos, 0, 0, $new_width, $new_height, $size[0], $size[1]);
        		}
				
				//Q: Changed to allow resized png to keep extension
        		//imagejpeg($destination, DIR_IMAGE_CACHE . $new_image, 90);
        		imagepng($destination, DIR_IMAGE_CACHE . $new_image, 9);

        		$image = $new_image;
        		break;			
    	}

    	imagedestroy($source);
    	imagedestroy($destination);

		ini_restore('memory_limit');

    	return $this->href(PATH_IMAGE_CACHE.'/'.$image);
  	}
  	
  	// Autodetect function to check if files exist in the image directory and auto-add them to the image database
  	function checkFiles() {

		$types = array('jpg','gif','jpeg','png');
		
		$files=glob(DIR_IMAGE.'*.*');
		if (!$files) { return; }
		$results = $this->database->getRows("select filename from image");
		foreach ($files as $file) {
			$pattern='/\.('.implode('|',$types).')$/i';
			if (preg_match($pattern,$file)) {
				$filename=basename($file);
				$exists=0;
				foreach ($results as $result) {
					if ($result['filename'] == $filename) { $exists=1; }
				}
				if (!$exists) { $this->addImage($filename); }
			}
		}
	}

	// If a new file exists that isn't in the database, add it.
	function addImage($filename) {

		$sql = "insert into image set filename = '?', date_added = now()";
		$sql = $this->database->parse($sql, $filename);
		$this->database->query($sql);

		$insert_id = $this->database->getLastId();
		$title = $this->getTitle($filename);
		
		$key = $this->language->languages[$this->config->get('config_language')]['language_id'];
		$sql = "insert into image_description set image_id = '?', language_id = '?', title = '?'";
		$sql = $this->database->parse($sql, $insert_id, $key, $title);
		$this->database->query($sql);
		
		$this->cache->delete('image');
	}
  	
  	// Create a title from the image filename (e.g. image_1.jpg --> Image 1)
  	function getTitle($file) {
		$str=$file;
		$str=pathinfo_filename($str);
		$str=urldecode($str);
		$str=str_replace(array('_','-','+','.'),' ',$str);
		$str=ucwords($str);
		return $str;
	}
}
?>
